/**
 * @file usr_adc_handle.h
 * @author 黑马小乌龟 (532352406@qq.com)
 * @brief 
 * @version 0.1
 * @date 2025-07-13
 * 
 * @copyright Copyright (c) 2025
 * 
 */
#ifndef USR_ADC_HANDLE__H_H
#define USR_ADC_HANDLE__H_H

#ifdef __cplusplus
extern "C"{
#endif
#include<stdint.h>
#include<stdio.h>

#include "hc32_ll.h"
#include "ev_hc32f334_lqfp64_bsp.h"

/* ADC unit instance for this example. */
#define ADC_UNIT       (CM_ADC1)
#define ADC_PERIPH_CLK (FCG3_PERIPH_ADC1)

/* Selects ADC channels that needed. */
// #define ADC_CH_POTENTIOMETER            (ADC_CH1)
#define ADC_Vin_CH   (ADC_CH9)
#define ADC_Vin_PORT (GPIO_PORT_B)
#define ADC_Vin_PIN  (GPIO_PIN_01)

#define ADC_Vout_CH   (ADC_CH6)
#define ADC_Vout_PORT (GPIO_PORT_A)
#define ADC_Vout_PIN  (GPIO_PIN_06)

#define ADC_CurrO_CH   (ADC_CH8)
#define ADC_CurrO_PORT (GPIO_PORT_B)
#define ADC_CurrO_PIN  (GPIO_PIN_00)

/* Selects ADC channels that needed. */
#define NTC_ADC_CH      (ADC_CH7)
#define NTC_ADC_CH_PORT (GPIO_PORT_A)
#define NTC_ADC_CH_PIN  (GPIO_PIN_07)

#define ADC2_DMA_BLOCK_SIZE (ADC_Vin_CH - NTC_ADC_CH+1)

#define ADC_CH_MIN                      (ADC_CH1)
#define ADC_CH_MAX                      (ADC_CH2)

/* ADC sequence to be used. */
#define ADC_SEQ                         (ADC_SEQ_A)
/* Flag of conversion end. */
#define ADC_EOC_FLAG                    (ADC_FLAG_EOCA)

/* ADC reference voltage. The voltage of pin VREFH. */
#define ADC_VREF                        (2800u)/*mV*/
#define ADC_VREF_IN_V                   (2.8f)

/* ADC accuracy(according to the resolution of ADC). */
#define ADC_ACCURACY                    (1UL << 12U)

#define MAX_OUT_VOLTAGE_CFG             (36u)/*V*/
#define MAX_OUT_VOL_ADC_VALUE           ((MAX_OUT_VOLTAGE_CFG*INPUT_VOL_RATIO*ADC_ACCURACY)/ADC_VREF_IN_V)

// #define INPUT_VOL_RATIO   0.075786f
#define INPUT_VOL_RATIO 0.075785582255f /*输入\输出电压的分压比 Rdw/(Rup+Rdw)*/
#define OUTPUT_VOL_RATIO  INPUT_VOL_RATIO
#define OUTPUT_CURR_RATIO 1

#define MINI_OUT_VOLTAGE 10u /*mV*/

#define GET_ADC_VOLUE_BY_OUT_VOL(vol /*mV*/)   (uint16_t)(((float32_t)vol * OUTPUT_VOL_RATIO * ADC_ACCURACY) / ADC_VREF)
#define MINI_OUT_VOLTAGE_IN_ADC_VALUE()        GET_ADC_VOLUE_BY_OUT_VOL(MINI_OUT_VOLTAGE)

/* Calculate the voltage(mV). */
#define ADC_CAL_VOL(adcVal) (uint16_t)(((((float32_t)(adcVal) * ADC_VREF) / ((float32_t)ADC_ACCURACY))) / INPUT_VOL_RATIO)

#define OUT_CURR_RATIO         34u
#define CURR_RESISTOR          0.01f /*10mR*/
#define CURR_RESISTOR_INVERSE  (1/CURR_RESISTOR)   // inverse

#define ADC_CAL_O_CURR(adcVal)                 (int32_t)((((float)(adcVal) * ADC_VREF) / ((float)ADC_ACCURACY * OUT_CURR_RATIO)) * CURR_RESISTOR_INVERSE /*10mR*/)
#define GET_ADC_VOLUE_BY_OUT_CURR(curr /*mA*/) ((curr)*CURR_RESISTOR * OUT_CURR_RATIO*ADC_ACCURACY/ADC_VREF)

#define IO_MAX_V_VS_ADC_REF  (2000u/*mV*//ADC_VREF)

/* Timeout value. */
#define ADC_TIMEOUT_VAL                 (1000U)

#define ADC_SEQA_HARDTRIG               (ADC_HARDTRIG_EVT0)
#define ADC_SEQA_AOS_TRIG_SEL           (AOS_ADC1_0)
#define ADC_SEQA_TRIG_EVT               (EVT_SRC_HRPWM_2_GCMP_E)
/*(EVT_SRC_HRPWM_2_GCMP_A)*/

#define ADC_SEQA_INT_PRIO               (DDL_IRQ_PRIO_03)
#define ADC_SEQA_INT_SRC                (INT_SRC_ADC1_EOCA)
#define ADC_SEQA_INT_IRQn               (INT014_IRQn)

#define ADC_DR_START                    ((uint32_t)&ADC_UNIT->DR6)

/**
 * Definitions of DMA.
 * 'APP_DMA_BLOCK_SIZE': 1~1024, inclusive. 1~16 for ADC1 and ADC2; 1~20 for ADC3.
 * 'APP_DMA_TRANS_COUNT': 0~65535, inclusive. 0: always transmit.
 */
#define DMA_UNIT                        (CM_DMA)
#define DMA_PERIPH_CLK                  (FCG0_PERIPH_DMA)
#define DMA_CH                          (DMA_CH0)
#define DMA_AOS_TRIG_SEL                (AOS_DMA_0)

#define DMA_TRANS_CNT                   (0U)
#define DMA_BLOCK_SIZE                  (1U)
#define DMA_DATA_WIDTH                  (DMA_DATAWIDTH_16BIT)
#define DMA_SRC_ADDR                    ADC_DR_START
#define DMA_DEST_ADDR                   ((uint32_t)(&m_au16AdcValue[0U]))

#define DMA_TRIG_EVT                    (EVT_SRC_ADC1_EOCA)

#define DMA_INT_TYPE                    (DMA_INT_BTC_CH0)
#define DMA_INT_IRQn                    (DMA_TC0_BTC0_IRQn)
#define DMA_INT_PRIO                    (DDL_IRQ_PRIO_03)
#define DMA_INT_FLAG                    (DMA_FLAG_BTC_CH0)
#define DMA_IRQ_HANDLER                 DMA_TC0_BTC0_Handler

#define ADC_EVENT_TRIGGER 1
extern uint16_t m_au16AdcValue[DMA_BLOCK_SIZE];
extern uint16_t m_au16AdcValue_adc3[1];
extern uint16_t m_au16AdcValue_adc2[ADC2_DMA_BLOCK_SIZE];

void AdcConfig(void);
const uint16_t *usr_adc_get_adc_value_buf(void);
// void AdcPolling(void);
void test_ADC1_SeqA_IrqCallback(void);
// int get_adc_finished_flg(void);
void Adc3_Config(void);
const uint16_t *usr_adc3_get_adc_value_buf(void);
void Adc2_Config(void);

#ifdef __cplusplus
}
#endif

#endif //USR_ADC_HANDLE__H_H


